﻿using System;
using System.Collections.Concurrent;

namespace zijian666.Converts;

public static class ConvertsMapping
{
    private static readonly ConcurrentDictionary<(Type source, Type target), IMappingRule> _mappings = new();


    public static void Map<TSource, TTarget>(Action<TSource, TTarget> action)
    {
        _mappings.AddOrUpdate((typeof(TSource), typeof(TTarget)), (_) => new MappingRule<TSource, TTarget>(action), (_, rule) => AddRule(rule, action));
    }

    static IMappingRule AddRule<TSource, TTarget>(IMappingRule rule, Action<TSource, TTarget> action)
    {
        ((MappingRule<TSource, TTarget>)rule).AddRule(action);
        return rule;
    }

    internal static void ApplyMap(object? source, object? target)
    {
        if (source is null || target is null)
        {
            return;
        }

        _mappings.TryGetValue((source.GetType(), target.GetType()), out var mapping);
        mapping?.Execute(source, target);
    }

}
